package com.mspbots.sync.wise.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.mspbots.sync.BaseGenericService;
import com.mspbots.sync.model.ExceptionLog;
import com.mspbots.sync.utils.WiseParamsUtils;
import com.mspbots.sync.wise.client.ClientProperties;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

/**
 * com.mspbots.sync.wise.service.ScheduleEntryService
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/10/17
 */
@Log4j2
@Service
public class ScheduleService extends BaseGenericService {

    public Flux<JsonNode> getEntriesOnly(Map<String, String> queryParams) {
        Integer tenant = Integer.parseInt(queryParams.get("tenantId"));
        if (StringUtils.isEmpty(queryParams.get("orderBy"))) {
            queryParams.put("orderBy", "id desc");
        }
        log.debug("This tenant {} get sync connect wise TicketOnly params {}.", tenant, queryParams);
        return this.onGetWiseProperties(tenant)
                .flatMapMany(configuration -> {
                    return this.cwWebClient.fetch("/schedule/entries",
                            WiseParamsUtils.mapToMultiValueMapBuild(queryParams))
                            .subscriberContext(ctx -> ctx.put("properties", configuration));
                });
    }

    public Flux<JsonNode> getEntries(ClientProperties configuration) {
        log.debug("This tenant {} start sync connect wise Schedule entry.", configuration.getTenantId());
        Mono<MultiValueMap<String, String>> paramsMono = this.loadRedisValue("sync-schedule-entries-" + configuration.getTenantId())
                .map(sysTime -> "lastUpdated >= [" + sysTime + "]")
                .map(queryStr -> WiseParamsUtils.paginationBuild("1", queryStr));
        return paramsMono.flatMapMany(params -> this.cwWebClient.fetch("/schedule/entries", params)
                .subscriberContext(ctx -> ctx.put("properties", configuration))
                .switchMap(jsonNode -> {
                    if (ObjectUtils.isEmpty(jsonNode.get("id"))) {
                        log.error("This tenant sync Schedule error.msg: {}", jsonNode);
                        this.messagingTemplate.convertAndSend("exception.log", ExceptionLog.builder()
                                .tenantId(configuration.getTenantId()).name("Connect wise")
                                .status(500).type("SYNC-WISE-SCHEDULE").msg("Connect wise sync Schedule entry error.")
                                .extend(jsonNode).build());
                        return Flux.empty();
                    }
                    return Flux.just(jsonNode);
                }))
                .doOnNext(entry -> this.loadRedisValue("sync-schedule-entries-" + configuration.getTenantId())
                        .subscribe(syncTime -> {
                                    LocalDateTime updateTime = LocalDateTime.parse(entry.findValue("lastUpdated").asText(),
                                            DateTimeFormatter.ISO_ZONED_DATE_TIME);
                                    if (syncTime.isBefore(updateTime)) {
                                        this.recordRedisValue("sync-schedule-entries-" + configuration.getTenantId(),
                                                updateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                                    }
                                }
                        ));

    }


}
